# -*- coding: utf-8 -*-
from PIL import Image
im=Image.open('parrot.png')
print(im.width,im.height,im.mode,im.format,type(im))
im.show()
#用PIL函数convert()将彩色RGB图像装换为灰度图像
im_g=im.convert('L')
im_g.show()
im_g.save('paroot_gray.png')
paroot_gray=Image.open('paroot_gray.png').show()


#使用matplotlib读取、保存和显示图像
from matplotlib import pyplot as plt
from matplotlib import image
im=image.imread('hill.png')
print(im.shape,im.dtype,type(im))
plt.figure(figsize=(10,10))
plt.imshow(im)
plt.axis('off')
plt.show()
im1=im
im1[im1<0.5]=0
plt.imshow(im1)
plt.axis('off')
plt.tight_layout()
plt.savefig('hill_dark.png')
hill_dark=image.imread('hill_dark.png')
plt.figure(figsize=(10,10))
plt.imshow(hill_dark)
plt.axis('off')
plt.tight_layout()
plt.show()


#使用matplotlib imshow()在显示时插值
from matplotlib import pyplot as plt
from matplotlib import image
im=image.imread('lena_small.jpg')
methods=['none','nearest','bilinear','bicubic','spline16','lanczos']
fig,axes=plt.subplots(nrows=2,ncols=3,figsize=(15,30),subplot_kw={'xticks':[],'yticks':[]})
fig.subplots_adjust(hspace=0.05,wspace=0.05)
for ax,interp_method in zip(axes.flat,methods):
    ax.imshow(im,interpolation=interp_method)
    ax.set_title(str(interp_method),size=20)
plt.tight_layout()
plt.show()


#使用scikit-image读取、保存和显示图像
from matplotlib import pyplot as plt
from skimage.io import imread,imsave,imshow
from skimage import color
im=imread('parrot.png')
plt.axis('off')
print(im.shape,im.dtype,type(im))
hsv=color.rgb2hsv(im)
hsv[:,:,1]=0.5
im1=color.hsv2rgb(hsv)
imshow(hsv)
imsave('parrot_hsv.png')
im=imread('parrot.png')


#使用scikit-image的astronaut数据集
from skimage import data
im=data.astronaut()
imshow(im)



#使用misc模块的face模块
from scipy import misc
from matplotlib import pyplot as plt
im=misc.face()
plt.axis('off')
plt.imshow(im)


#使用imageio读取图像
import imageio
from matplotlib import pyplot as plt
im=imageio.imread('veg.jpg')
print(type(im),im.shape,im.dtype)
plt.imshow(im)
plt.axis('off')
plt.show()


#RGB图像可保存为jpg格式，RGBA则不可以，要先转换为RGB
from PIL import Image
im=Image.open('parrot.png')
print(im.mode)
im.save('parrot.jpg')


im=Image.open('hill.png')
print(im.mode)
im.convert('RGB').save('格式变换的hill.jpg')


#一种图像模式转换为一种图像模式
#彩色图像转换为灰度图像
from skimage.io import imread
from skimage import color
import matplotlib.pyplot as plt
im=imread('Ishihara.png')
print(im.shape)
im_g=color.rgb2gray(im)
plt.subplot(121)
plt.imshow(im,cmap='gray')
plt.axis('off')
plt.subplot(122)
plt.imshow(im_g,cmap='gray')
plt.axis('off')
plt.show()



#从一个空间换到另一个空间
#H色调,S饱和度,V名度
from skimage.io import imread
from skimage import color
import matplotlib.pyplot as plt
im=imread('parrot.png')
im_hsv=color.rgb2hsv(im)
plt.figure(figsize=(10,8))
plt.subplot(221)
plt.imshow(im_hsv[...,0])
plt.title('h',size=20)
plt.axis('off')
plt.subplot(222)
plt.imshow(im_hsv[...,1])
plt.title('s',size=20)
plt.axis('off')
plt.subplot(223)
plt.imshow(im_hsv[...,2])
plt.title('v',size=20)
plt.axis('off')



#用于存储图像的数据结构
#转换数据结构，使用PILde Image对象转换为numpy ndarray
from PIL import Image
from skimage.io import imshow
import numpy as np
import matplotlib.pyplot as plt
im=Image.open('flowers.png')
im=np.array(im)
imshow(im)
plt.axis('off')
plt.show()




#将numpy ndarray转换为PIL的image对象
from PIL import Image
from skimage import io
im=io.imread('flowers.png')
im=Image.fromarray(im)
im.show()



#使用numpy数组的切片和掩模在Lena图像上创建圆形掩模
from matplotlib import image
import numpy as np
import matplotlib.pyplot as plt
lena=image.imread('lena.jpg')
print(lena[0,40])
lx,ly,_=lena.shape
X,Y=np.ogrid[0:lx,0:ly]
mask=(X-lx/2)**2+(Y-ly/2)**2>lx*ly/4
lena.flags.writeable=True#解决assignment destination is read-only，原图像只是只读模式不支持修改
for i in range(len(mask)):
    for j in range(len(mask)):
        if mask[i,j]==True:
            lena[i,j,:]=0
# lena[mask,:]=0
plt.figure(figsize=(10,10))
plt.imshow(lena)
plt.axis('off')
plt.show()



#简单的图像变形，使用交叉溶解的两个图像的阿尔法a混合
from matplotlib import image
from matplotlib import pyplot as plt
import numpy as np
im1=image.imread('messi.png')/255
im2=image.imread('ronaldo.png')/255
i=1
plt.figure(figsize=(18,15))
for alpha in np.linspace(0,1,20):
    plt.subplot(4,5,i)
    plt.imshow((1-alpha)*im1+alpha*im2)
    plt.axis('off')
    i+=1
plt.subplots_adjust(wspace=0.05,hspace=0.05)
plt.show()



#使用PIL进行图像处理
#进行裁剪crop操作
from PIL import Image
import numpy as np
im=Image.open('parrot.png')
print(im.width,im.height,im.mode,im.format)
im_c=im.crop((200,25,320,150))#(左,上,右,下)
im_c.show()

#调整图像尺寸resize(),长高都乘5，放大25倍,双线性插值
im1=Image.open('clock.png')
print(im1.width,im1.height,im1.mode,im1.format)
im1.show()
im1_large=im1.resize((im1.width*5,im1.height*5),Image.BILINEAR)
im1_large.show()

#调整为较小尺寸的图像
im2=Image.open('vic.png')
print(im2.width,im2.height)
im2.show()
im2_small=im2.resize((im2.width//5,im2.height//5),Image.ANTIALIAS)#抗混叠技术
im2_small.show()

#图像负片,用像素点最大值255减去该点像素点得到反转像素值
im3=Image.open('parrot.png')
im3.show()
im3_t=im3.point(lambda x:255-x)
im3_t.show()

#将RGB图像转换为灰度图像
im_g=im3.convert('L')#L参数表示将RGB彩色图像转换成灰度图像
im_g.show()

#1.对数变换
im_g_log=im_g.point(lambda x:255*np.log(1+x/255))
im_g_log.show()

#2.幂律变换，Y=0.6
im_g_y=im_g.point(lambda x:255*(x/255)**0.6)
im_g_y.show()


#一些几何变换
#1.镜像图像，transpose()函数
im.transpose(Image.FLIP_LEFT_RIGHT).show()#水平方向翻转
im.transpose(Image.FLIP_TOP_BOTTOM).show()#垂直翻转

#2.旋转图像，rotate()函数
im_45=im.rotate(45)#图像旋转45度
im_45.show()
im_90=im.rotate(90)#图像旋转90度
im_90.show()

#3.在图像上应用仿射变换
#这种变换通过反向映射（扭曲）来实现
#该函数可用于缩放、平移、旋转和剪切图像
im=Image.open('parrot.png')
im_transform=im.transform((int(1.4*im.width),im.height),Image.AFFINE,data=(1,-0.5,0,0,1,0))
im_transform.show()

#4.透视变换
#通过使用Image.PERSPECTIVE参数，可以让transform()函数对图像进行透视变换
params=[1,0.1,0,-0.1,0.5,0,-0.005,-0.005]
im_ts=im.transform((im.width//3,im.height),Image.PERSPECTIVE,params,Image.BICUBIC)
im_ts.show()

#更改图像的像素值，添加噪声
im_copy=im.copy()#复制图层
n=5000
x,y=np.random.randint(0,im.width,n),np.random.randint(0,im.height,n)
for (x,y) in zip(x,y):
    im_copy.putpixel((x,y),((0,0,0) if np.random.rand()<0.5 else(255,255,255)))
im_copy.show()

#在图像上绘制椭圆
from PIL import ImageDraw
from PIL import Image
from PIL import ImageFont
from PIL import ImageStat as stat
from matplotlib import pyplot as plt
from PIL.ImageChops import add,subtract,multiply,difference,screen
import numpy as np
im=Image.open('parrot.png')
draw=ImageDraw.Draw(im)
draw.ellipse((125,125,200,250),fill=(255,255,255,128))
del draw
im.show()

#在图像上添加文本
draw=ImageDraw.Draw(im)
font=ImageFont.truetype('arial.ttf',23)
draw.text((10,5),'Welcome to image processing with python',font=font)
del draw
im.show()

#创建略缩图
im=Image.open('parrot.png')
im_thumbnail=im.copy()
im_thumbnail.thumbnail((100,50))
im.paste(im_thumbnail,(400,300))
im.save('parrot_thumb.jpg')
im.show()


#计算图像的基本统计信息
im=Image.open('parrot.png')                                                                                                                                                                                                                                                                                                                                                                                                                  
s=stat.Stat(im)
print(s.extrema)
print(s.count)
print(s.mean)
print(s.median)
print(s.stddev)

#绘制RGB通道像素值的直方图
im=Image.open('parrot.png') 
pl=im.histogram()
plt.bar(range(256),pl[:256],color='r',alpha=0.5)
plt.bar(range(256),pl[256:256*2],color='g',alpha=0.4)
plt.bar(range(256),pl[256*2:],color='b',alpha=0.3)
plt.show()

#分离图像的RGB通道，用split()实现
im=Image.open('parrot.png') 
ch_r,ch_g,ch_b=im.split()
plt.figure(figsize=(18,6))
plt.subplot(1,3,1);plt.imshow(ch_r,cmap=plt.cm.Reds);plt.axis('off')
plt.subplot(1,3,2);plt.imshow(ch_g,cmap=plt.cm.Greens);plt.axis('off')
plt.subplot(1,3,3);plt.imshow(ch_b,cmap=plt.cm.Blues);plt.axis('off')
plt.tight_layout()
plt.show()

#合并图像的多个通道，使用merge()函数
im=Image.merge('RGB',(ch_b,ch_g,ch_r))#将分离出来的三个通道合并，按BGR合并
im.show()

#两幅图的a混合，混合公式:out=(1.0-a)image1+aimage2
#可知如果a=0则返回第一幅图，如果a=1返回第二幅图
#两幅图必须大小和模式相同
im1=Image.open('parrot.png')
im2=Image.open('hill.png')
im1=im1.convert('RGBA')#转换图片模式为RGBA
#im2=im2.resize((im1.width,im1.height),Image.BILINEAR)#转换图片的大小，使两张图大小一致
im=Image.blend(im1,im2,alpha=0.5)#设置a=0.5
im.show()

#两幅图的叠加
#叠加图片大小相同
#通过像素相乘将一个图像叠加到另一个图像顶部
im1=Image.open('parrot.png')
im2=Image.open('hill.png')
im2=im2.convert('RGB')
# im1=im1.convert('RGBA')
im=multiply(im1,im2)
im.show()

#将两幅图相加，逐个像素点相加
add(im1,im2).show()

#计算两图像之间的差值
#图像差值可用来检测两个图像之间的变化
im1=Image.open('goal1.png')
im2=Image.open('goal2.png')
im=difference(im1, im2)
im.save('goal_diff,.png')
#中文显示
plt.rcParams['font.sans-serif']=['FangSong']#设置字体为仿宋
plt.rcParams['axes.unicode_minus']=False#解决负号显示问题
plt.subplot(311)
plt.imshow(im1)
plt.title('第一帧图像')
plt.axis('off')

plt.subplot(312)
plt.imshow(im2)
plt.title('第二帧图像')
plt.axis('off')

plt.subplot(313)
plt.imshow(im)
plt.title('差值图像')
plt.axis('off')
plt.show()
    
#减去两个图像负片:substract()
#叠加两个图像负片:screen()




#使用scikit-image进行图像操作

#使用warp()函数进行反向扭曲和几何转换
#在图像上应用仿射变换，先使用SimilarityTransform()计算变换矩阵
#然后使用warp()来执行变换
from skimage.io import imread
from skimage.transform import SimilarityTransform,warp,swirl
import matplotlib.pyplot as plt
import numpy as np
from skimage import color,viewer,exposure,img_as_float,data
from skimage.util import invert,random_noise,montage

im=imread('parrot.png')
tform=SimilarityTransform(scale=0.9,rotation=np.pi/4,translation=(im.shape[0]/2,-100))
warped=warp(im, tform)
#中文显示
plt.rcParams['font.sans-serif']=['FangSong']#设置字体为仿宋
plt.rcParams['axes.unicode_minus']=False#解决负号显示问题
plt.imshow(warped)
plt.axis('off')
plt.title('鹦鹉图像的仿射变换')
plt.show()

#应用旋转流变换(swirl transform),非线性变换
#参数strength是旋流量参数，radius是以像素表示旋转程度，rotation表示添加旋转角度
im=imread('parrot.png')
swirled=swirl(im,rotation=0,strength=15,radius=200)
#中文显示
plt.rcParams['font.sans-serif']=['FangSong']#设置字体为仿宋
plt.rcParams['axes.unicode_minus']=False#解决负号显示问题
plt.imshow(swirled)
plt.title('鹦鹉图像的旋转流变换')
plt.axis('off')
plt.show()

#在图像中随机添加高斯噪声:random_noise()
im=img_as_float(imread('parrot.png'))
plt.figure(figsize=(15,12))
sigmas=[0.1,0.25,0.5,1]
for i in range(4):
    noisy=random_noise(im,var=sigmas[i]**2)
    plt.subplot(2,2,i+1)
    plt.imshow(noisy)
    plt.axis('off')
    plt.title('sigma为'+str(sigmas[i])+'的高斯噪声图像',size=20)
plt.tight_layout()
plt.show()

#计算图像的累计分布函数(Cumulative Distribution Function,CDF)，可以使用cumulative_distribution()




#使用matplotlib进行图像操作
# 可以使用Matplotlib库中的pylab模块进行图像操作1
#绘制图像轮廓线，图像轮廓线是一条连接所有像素的曲线
#绘制爱因斯坦的灰度图像轮廓线和填充轮廓
from matplotlib import pyplot as plt
from matplotlib import pylab
from matplotlib import image
from skimage.color import rgb2gray
import numpy as np
im=rgb2gray(image.imread('einstein.jpg'))#读取图片数据为0-1的数据矩阵
plt.figure(figsize=(20,8))
plt.subplot(131)
plt.imshow(im,cmap='gray')
plt.title('原始图像',size=20)
plt.axis('off')

plt.subplot(132)
plt.contour(np.flipud(im),color='k',levels=np.logspace(-15,15,100))
plt.title('图像轮廓线',size=20)
plt.axis('off')

plt.subplot(133)
plt.contourf(np.flipud(im),cmap='inferno')
plt.title('图像填充轮廓图',size=20)
plt.axis('off')
plt.show()


